﻿#define _CRT_SECURE_NO_WARNINGS 1
//#include <stdio.h>
//int main()
//{
//	printf("%d\n", 153);
//	printf("%d\n", 0153);//这里的153前面有0,是8进制数字
//	int a = 0x6b;
//	return 0;
//}
//#include <stdio.h>
//int main()
//{
//	int a = -10;//a占4个字节,32个比特位,又因为是负数,最高位是1,
//	//10000000 00000000 00000000 00001010 -- 原码
//	//11111111 11111111 11111111 11110101 -- 反码 -- 符号位不变,其他位取反
//	//11111111 11111111 11111111 11110110 -- 补码 -- 反码+1
//
//	int b = 10;//b占4个字节,32个比特位,是正数,最高位是0
//	//00000000 00000000 00000000 00001010 -- 原码
//	//00000000 00000000 00000000 00001010 -- 反码
//	//00000000 00000000 00000000 00001010 -- 补码  -- 正数原反补一样
//
//	unsigned int c = 10;//c占4个字节,32个比特位,是无符号类型,最高位是数值位
//	//00000000 00000000 00000000 00001010 -- 原码
//	//00000000 00000000 00000000 00001010 -- 反码
//	//00000000 00000000 00000000 00001010 -- 补码  -- 正数原反补一样
//
//	//-10补码
//	//11111111 11111111 11111111 11110110 -- 补码
//	//10000000 00000000 00000000 00001001 -- 取反 - 注意,这不是反码
//	//10000000 00000000 00000000 00001010 -- 原码
//
//
//	return 0;
//}

//int main()
//{
//	//1 - 1；
//	//可以转换为1+(-1)
//	//尝试用原码
//	//00000000 00000000 00000000 00000001 - 1的原码
//	//10000000 00000000 00000000 00000001 - -1的原码
//	//10000000 00000000 00000000 00000010 - -2,相加结果是错误的
//	// 
//	//使用补码计算
//	//00000000 00000000 00000000 00000001 - 1的原码,反码,补码一样
//	//11111111 11111111 11111111 11111111 - -1的补码
//	//10000000 00000000 00000000 000000000 - 相加的结果
//	//0000000 00000000 00000000 000000000 - 整型运算,存32个位,最高位1丢了,结果是0
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 10;
//	int b = a << 1;//把a向左移动一位
//	printf("a = %d\n", a);
//	printf("b = %d\n", b);
//	return 0;
//}
/*
移动的是存储在内存中的二进制位(补码)
00000000 00000000 00000000 00001010 - 10的原码,反码,补码
00000000 00000000 00000000 00010100 - 移动1位的结果,20
这里b是20,a还是原来的值不会变
a向左移动一位,这个动作本质上不会改变a的
*/


//#include <stdio.h>
//int main()
//{
//	//如果想让a的值改变,那么就可以这样写
//	int a = 10;
//	a = a << 1; //a <<= 1;
//	printf("a = %d\n", a);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	//负数左移
//	int a = -1;
//	int b = a << 1;
//	printf("a = %d\n", a);//-1
//	printf("b = %d\n", b);//-2
//	return 0;
//}
/*
10000000 00000000 00000000 00000001 - -1的原码
11111111 11111111 11111111 11111110 - -1的反码
11111111 11111111 11111111 11111111 - -1的补码

11111111 11111111 11111111 11111110 - 左移的结果(补码)
10000000 00000000 00000000 00000001 - 左移的结果取反
10000000 00000000 00000000 00000010 - 左移结果取反加1(原码) -2
//左移一位有*2的效果
*/

//#include <stdio.h>
//int main()
//{
//	int a = -10;
//	int b = a >> 1;
//	printf("a = %d\n", a);
//	printf("b = %d\n", b);
//	return 0;
//}
/*
10000000 00000000 00000000 00001010 - -10原码
11111111 11111111 11111111 11110101 - -10反码
11111111 11111111 11111111 11110110 - -10补码

//逻辑右移 - 左边用0填充,右边丢弃
01111111 11111111 11111111 11111011 - 右移的结果,成整数了,正数的原反补相同

//算数右移 - 左边用原该值的符号位填充,右边丢弃
11111111 11111111 11111111 11111011 - 右移的结果(补码)
10000000 00000000 00000000 00000100 - 右移的结果取反
10000000 00000000 00000000 00000101 - 右移取反加1(原码) -5
*/

//#include <stdio.h>
//int main()
//{
//	int num = 10;
//	num >> -1;
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 6;
//	//00000000 00000000 00000000 00000110 - 6的原反补码
//	
//	int b = -7;
//	//10000000 00000000 00000000 00000111 - -7的原码
//	//11111111 11111111 11111111 11111000 - -7的反码
//	//11111111 11111111 11111111 11111001 - -7的补码
//
//	int c = a ^ b;
//	//00000000 00000000 00000000 00000110 - 6的补码
//	//^
//	//11111111 11111111 11111111 11111001 - -7的补码
//	//11111111 11111111 11111111 11111111 - 异或后的结果(补码)
//	//10000000 00000000 00000000 00000000 - 异或后取反
//	//10000000 00000000 00000000 00000001 - 异或后取反加1(原码) -1
//	//a和b的对应的二进制位进行按位异或,相同为0,相异为1
//	printf("%d\n", c);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 0;
//	printf("%d\n", ~a);
//	//~ 按(2进制)位取反
//	//00000000 00000000 00000000 00000000 - 0的原反补码
//	//11111111 11111111 11111111 11111111 - 取反的结果(补码)
//	//10000000 00000000 00000000 00000000 - 取反的结果取反
//	//10000000 00000000 00000000 00000001 - 取反的结果加1 -1
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 3;
//	int b = 6;
//	printf("交换前:a = %d,b = %d\n", a, b);
//	a = a ^ b;
//
//
//	b = a ^ b;//替换为b = a ^ b ^ b,因为上面写了a = a ^ b,那么将这里的a替换
//	//b^b = 0,a ^ 0 = a(上面推理的),将原来的a放到b里面
//
//
//	a = a ^ b;//替换为a = a ^ b ^ b,因为上面写了a = a ^ b,那么将这里的a替换
//	//此时最后一个b里面是原来的a,那么就是a = a ^ b ^ a,a^a = 0,0 ^ b = b，将b
//	//放到a里面,这样就完成了交换
//
//	//其实这里面还是把a^b这个表达式结果放到a里面,这个a可以把它想象成一个密码,
//	//这个密码遇到原来的b就能找出原来的a,这个密码遇到原来的a,b里面放的就是原来
//	//的a,就能翻译出原来的b。
//	//异或操作符在运算的时候是相同为0,相异为1的,它是不存在进位的,既然不存在进位
//	//那么就没有可能溢出的
//	printf("交换后:a = %d,b = %d\n", a, b);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 3;
//	int b = 6;
//	printf("交换前:a = %d,b = %d\n", a, b);
//	int c = 0;
//	c = a;
//	a = b;
//	b = c;
//	printf("交换后:a = %d,b = %d\n", a, b);
//	return 0;
//}


//#include <stdio.h>
//int main()
//{
//	int a = 3;
//	int b = 6;
//	printf("交换前:a = %d,b = %d\n", a, b);
//	a = a ^ b;
//	b = a ^ b;
//	a = a ^ b;
//	printf("交换后:a = %d,b = %d\n", a, b);
//	return 0;
//}

//#include <stdio.h>
//int count_bit_one(unsigned int n)
//{
//	int count = 0;
//	while (n)
//	{
//		if (n % 2 == 1)
//			count++;
//		n /= 2;
//	}
//	return count;
//}
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int ret = count_bit_one(n);
//	printf("%d\n", ret);
//	return 0;
//}


//#include <stdio.h>
//int count_bit_one(int n)
//{
//	int count = 0;
//	for (int i = 0; i < 32; i++)
//	{
//		if (((n >> i) & 1) == 1)//这里是拿二进制位算的,不管有符号还是无符号
//			count++;
//	}
//	return count;
//}
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int ret = count_bit_one(n);
//	printf("%d\n", ret);
//	return 0;
//}

//#include <stdio.h>
//int count_bit_one(int n)
//{
//	int count = 0;
//	while (n)
//	{
//		n = n & (n - 1);
//		count++;
//	}
//	return count;
//}
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int ret = count_bit_one(n);
//	printf("%d\n", ret);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	if ((n & (n - 1)) == 0)
//		printf("%d是2的次方数", n);
//	else
//		printf("%d不是2的次方数", n);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 13;
//	//将第5位改为1
//	//00000000 00000000 00000000 00001101 - 13的原反补码
//	//00000000 00000000 00000000 00010000 - 给第5位或1就变成1,其他位或0不变
//	//如果第5位原来是1,或1就还是1,如果原来是0,或1就变成1
//	//其他位或0,如果其他位是1,或0还是1,如果其他位是0,或0还是0
//	//那么或的那个数怎么来呢?现在是第5位,如果是第n位呢?
//	int n = 5;//要改变的第5位
//	//1 << (n - 1)，这样就可以得到或的那个二进制位了
//	//00000000 00000000 00000000 00000001
//	//<<4(n-1)
//	//00000000 00000000 00000000 00010000
//	a = a | (1 << (n - 1));
//	printf("%d\n", a);
//	//将第5为改为0
//	//00000000 00000000 00000000 00011101 - 29的补码
//	//11111111 11111111 11111111 11101111 - 给第5位与0就变成0,其他为与1不变
//	//如果第5位原来是1,与0就变成0,如果原来是0,与0就不变
//	//其他位与0,如果其他位是1,与1还是1,如果其他位是0,与1还是0
//	//那么与的那个数怎么来呢?现在是第5位,如果是第m位呢?
//	int m = 5;//改改变的第5位
//	//~(1 << (n - 1))，这样就可以得到与的那个二进制位了
//	//00000000 00000000 00000000 00000001
//	//<<4(n-1)
//	//00000000 00000000 00000000 00010000
//	//~(按位取反)
//	//11111111 11111111 11111111 11101111
//	a = a & (~(a << (m - 1)));
//	printf("%d\n", a);
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a = 1;
//	int b = 2;
//	int c = (a > b, a = b + 10, b = a + 1);
//	//逗号表达式会从左向右依次计算
//	//a > b这个表达式虽然为假,但是对a和b没有任何影响
//	//a = b + 10,a = 12
//	//b = a + 1,b = 13
//	//逗号表达式的结果是最后一个表达式的结果
//	printf("%d\n", c); //13
//	return 0;
//}

//int main()
//{
//	int a = 0;
//	int b = 0;
//	int c = 0;
//	int d = 0;
//	if (a = b + 1, c = a / 2, d > 0)//前面两个表达式计算完,d>0就进入if,否则不进入
//	{
//		//所有if语句这里也可以写逗号表达式,这个表达式依然从左到右依次计算
//		//但正真是看最后一个表达式结果来看if要不要进去
//	}
//	return 0;
//}

//代码3
//这是一段伪代码,所谓伪代码就是不是真实的代码,一段假的代码
//int main()
//{
//	int a = get_val();
//	count_val(a);
//	while (a > 0)
//	{
//		//业务处理
//		//...
//		a = get_val();
//		count_val(a);
//	}
//	//如果使⽤逗号表达式，改写:
//	while (a = get_val(), count_val(a), a > 0)
//	{
//		//业务处理
//
//	}
//	return 0;
//}


//int main()
//{
//	//这里的[]不算下标引用操作符,这是在指定大小,不是在访问下标
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//
//	arr[4];//数组中下标为4的元素
//	//[]下标引用操作符 - 操作数是arr,4
//	return 0;
//}

//int Add(int x, int y)
//{
//	return x + y;
//}
//int main()
//{
//	printf("hello world");//()就是函数调用操作符,操作数是:printf,"hello world"
//	printf("%d\n", 100);//操作数是:printf,"%d\n",100
//	int ret = Add(3, 5);//操作数是Add,3,5
//	//函数调用操作数最少有几个操作数?
//	//1个,函数名,因为当有一个函数不传参的时候直接去使用它。但是至少有一个函数名
//	return 0;
//}

//struct tag//struct - 结构体关键字 tag - 标签名(自己定义)
//{
//	member - list;//成员列表
//}variable - list;//变量列表

////学生类型
//#include <stdio.h>
//struct Student
//{
//	//成员变量
//	char name[20];//姓名
//	int age;//年龄
//	float score;
//}s4 = { "wangwu",22,91.5 } , s5;//s4,s5也是用学生类型创建的对象,这里可以写一个,可以写多个,也可以不写,也是全局变量
//struct Student s3 = {"lisi",21,88.0};//全局变量
//struct Point
//{
//	int x;
//	int y;
//};
//struct S
//{
//	char ch;
//	struct Point p;//结构体中有一个结构体变量
//	int arr[10];
//	double d;
//};
//int main()
//{
//	//用结构体类型创建结构体变量
//	struct Student s1 = {"cuihua",20,98.0};//用学生类型创建对象s1
//	struct Student s2 = {"zhangsan",18,69.8};//用学生类型创建对象s2
//	struct Point p = { 10,20 };
//	struct S s = { 'a',{12,13},{1,2,3,4,5,6,7,8,9},3.14 };
//	//打印
//	printf("%c\n", s.ch);//打印s结构体变量中的ch
//	printf("坐标是:%d %d\n", s.p.x, s.p.y);
//	printf("%d\n", s.arr[0]);
//	printf("%lf\n", s.d);
//	//也可以修改,把printf修改为scanf
//	//结构体变量.结构体成员名
//	return 0;
//}


//struct Point
//{
//	int x;
//	int y;
//};
//struct S
//{
//	char ch;
//	struct Point p;//结构体中有一个结构体变量
//	int arr[10];
//	double d;
//};
//int main()
//{
//	struct S s = {'a',{12,13},{1,2,3,4,5,6,7,8,9},3.14 };//结构体嵌套初始化
//	return 0;
//}

//#include <stdio.h>
//struct Student
//{
//	char name[20];
//	int age;
//	float score;
//};
//void Print1(struct Student tmp)
//{
//	printf("%s %d %f\n", tmp.name, tmp.age, tmp.score);
//}
//void Print2(struct Student* tmp)//struct Student* - 结构体指针类型
//{
//	//tmp - 结构体指针变量
//	//使用方式:结构体指针->成员名字
//	printf("%s %d %f\n", tmp->name, tmp->age, tmp->score);
//}
//int main()
//{
//	struct Student s = {"zhangsan",19,88.5f};
//	printf("%s %d %f\n", s.name, s.age, s.score);
//	Print1(s);
//	Print2(&s);//传的是地址
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int r = 3 + 4 * 5;
//	//当两个操作符相邻的时候,优先级高的先执行,这里*的优先级高,所有先算4*5,然后+3.
//	//如果想要计算3+4的话,可以使用()的方式来改变它的优先级
//	return 0;
//}

//#include <stdio.h>
////相邻操作符,优先级高的执行
////相邻操作符的优先级相同的情况下,结合性说了算
//int main()
//{
//	
//	int r = 3 + 4 + 5;
//	//'+'结合性是从左到右,先算3 + 4，得出7再加上5
//	return 0;
//}

//圆括号 ( () )
//自增运算符 ( ++ ),自减运算符 ( -- )
//单目运算符 ( +和- )
//乘法 ( * ) , 除法 ( / )
//加法 ( + ) , 减法 ( - )
//关系运算符 ( < 、> 等)
//赋值运算符 ( = )

//#include <stdio.h>
//int main()
//{
//	//int a = 10;
//	//int b = 20;
//	//int c = a + b;//a和b这两个整型计算得时候什么都不发生,因为都是整型
//
//	char a = 20;
//	//00000000 00000000 00000000 00010100 - 补够32个位 - 20的原反补
//	//现在要把20放到a里面,可是a是char类型,只能存8个比特位,存的是低八个位
//	//00010100 - a里面正真放的数据
//	char b = 130;
//	//00000000 00000000 00000000 10000010 - 补够32个位 - 130的原反补
//	//现在要把130放到b里面, 可是b是char类型, 只能存8个比特位, 存的是低八个位
//	//10000010 - b里面正真放的数据
//	char c = a + b;
//	//00010100 - a里面正真放的数据
//	//+
//	//10000010 - b里面正真放的数据
//	//在相加之前a和b都不到一个整型的大小,所以要整型提升
//	//那么我们知道int其实就是signed int，这是规定。
//	//但是char是不是signed char,这取决于编译器
//	//在VS上char就等价于signed char
//	//那么既然是有符号的char,那么(00010100)的最高位就是符号位
//	//前面说过有符号整数提升是按照变量的数据类型的符号位来提升的(补0)。
//	//00000000 00000000 00000000 00010100  - a提升后的结果,b也一样(最高位补1)
//	//11111111 11111111 11111111 10000010  - b提升后的结果
//	//计算
//	//11111111 11111111 11111111 10010110  - 相加后的结果(补码)
//	//将加完之后的结果放到c里面,c是char类型,只能存放最低八个位(截断)
//	//10010110 - c(补码)
//	//%d - 打印有符号的整数,c是char类型,所以还得整型提升
//	//11111111 11111111 11111111 10010110 - (补码)
//	//10000000 00000000 00000000 01101001 - 补码取反
//	//10000000 00000000 00000000 01101010 - 补码取反+1
//	//结果是 -106
//	printf("%d\n", c);//-106
//	return 0;
//}

//#include <stdio.h>
//int main()
//{
//	int a;
//	double b;
//	a + b;
//	//计算a+b的话会把int类型的a转换成double类型,向上转换
//	return 0;
//}

//表达式3
//#include <stdio.h>
//int main()
//{
//	int i = 10;
//	i = i-- - --i * (i = -3) * i++ + ++i;
//	printf("i = %d\n", i);
//	return 0;
//}

//#include <stdio.h>
//int fun()
//{
//	static int count = 1;
//	return ++count;
//}
//int main()
//{
//	int answer;
//	answer = fun() - fun() * fun();
//	printf("%d\n", answer);//输出多少？
//	return 0;
//}

//表达式5
#include <stdio.h>
int main()
{
	int i = 1;
	int ret = (++i) + (++i) + (++i);
	printf("%d\n", ret);
	printf("%d\n", i);
	return 0;
}
//尝试在linux环境gcc编译器，VS2013环境下都执⾏，看结果。

